package com.rem.designPattern.template模版.improve;

/**
 * 模板模式
 * 定义一个操作中的算法的骨架，而将一些步骤延迟到子类中。TemplateMethod 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
 * <p>
 * 制作豆浆--加入钩子方法
 *
 * @author Rem
 * @date 2022-11-18
 */
public abstract class SoyaMilk {
    /**
     * 是否原味豆浆
     */
    boolean isPlain = false;

    /**
     * 模板方法，定义为final禁止覆写
     */
    public final void make() {
        System.out.println(">>>>>>豆浆制作开始<<<<<<");
        useSoyBean();
        if (customAddIngredients()) {
            addIngredients();
        }
        soak();
        mash();
        System.out.println(">>>>>>豆浆制作结束<<<<<<");
    }

    protected boolean customAddIngredients() {
        return isPlain;
    }

    protected void useSoyBean() {
        System.out.println("Step1. 选用上好的黄豆");
    }

    /**
     * 添加配料
     */
    protected abstract void addIngredients();

    protected void soak() {
        String str = "";
        if (!isPlain) {
            str = "和配料";
        }
        System.out.println("Step3. 对黄豆" + str + "进行水洗浸泡");
    }

    protected void mash() {
        String str = "";
        if (!isPlain) {
            str = "和配料";
        }
        System.out.println("Step4. 将充分浸泡过的黄豆" + str + "放入豆浆机中，开始打豆浆");
    }
}

/**
 * 花生豆浆
 */
class PeanutSoyaMilk extends SoyaMilk {
    @Override
    protected void addIngredients() {
        System.out.println("Step2. 加入上好的花生");
    }
}

/**
 * 红豆豆浆
 */
class RedBeanSoyaMilk extends SoyaMilk {
    @Override
    protected void addIngredients() {
        System.out.println("Step2. 加入上好的红豆");
    }
}

/**
 * 原味豆浆
 */
class PureSoyaMilk extends SoyaMilk {
    @Override
    protected void addIngredients() {
        // 空实现即可
    }

    @Override
    protected boolean customAddIngredients() {
        isPlain = true;
        return isPlain;
    }
}